#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <time.h>

#define HEIGHT 8
#define WIDTH 20
#define MAX_LENGH 50

enum MOVE_DIR {UP=-1,DOWN=1,LEFT=2,RIGHT=4};

struct ss
{
	int x;
	int y;
	enum MOVE_DIR dir;
}snake[MAX_LENGH];
//int snake[MAX_LENGH][2];
int snake_lengh = 3;
int score = 0;
enum MOVE_DIR cur_dir = DOWN;

struct ss food;

void init()                   //初始化snake
{
	int i;
	srand(time(NULL));
	for( i = 0;i < snake_lengh;i++)
	{
		snake[i].x = 3;
		snake[i].y = 3+i;
		snake[i].dir = RIGHT;
	}
	food.x = rand()%(HEIGHT-2)+1;
	food.y = rand()%(WIDTH-2)+1;
}

void display()                //显示snake和外部
{
	int i;
	char a[HEIGHT][WIDTH+2]={"====================\n",
			 	 "|                  |\n",
			 	 "|                  |\n",
				 "|                  |\n",
				 "|                  |\n",
				 "|                  |\n",
				 "|                  |\n",
				 "====================\n"};
	for (i = 0;i < snake_lengh;i++)
		a[snake[i].x][snake[i].y]='*';
	a[food.x][food.y]='#';
	system("clear");
	for (i = 0;i < HEIGHT;i++)
		printf("%s",a[i]);
	printf("当前分数为%d.\n",score);
}

int snake_move()             //对snake的移动以及撞墙的反应(目前为撞墙
{                            //或者遇到身体停止
	struct ss head;
	head = snake[snake_lengh-1];
	int i,j,lemp = 0;
	
	if (cur_dir == RIGHT||cur_dir == LEFT)

		head.y += cur_dir-3;
	else
		head.x += cur_dir;
	if (head.x == 0||head.x == HEIGHT-1||head.y==0||head.y==WIDTH-1)
		return 0;
	for (j = 0;j < snake_lengh;j++)
	{
		if(snake[j].x==head.x&&snake[j].y==head.y)
			return 0 ;
	}
	if (head.x == food.x && head.y == food.y)
	{
		head.dir = cur_dir ;
		snake[snake_lengh] = head;
		snake_lengh++;
		score++;
		while(lemp == 0)
		{
			food.x = rand()%(HEIGHT-2)+1;
			food.y = rand()%(WIDTH-2)+1;
			for (j=0;j < snake_lengh;j++)
			{
				if (snake[j].x==food.x&&snake[j].y==food.y)
				{
					lemp=0;
					break;
				}
				lemp=1;
			}
		}



	}
 	else
	{
		for (i=0;i<snake_lengh-1;i++)
		{
			snake[i].x = snake[i+1].x;
			snake[i].y = snake[i+1].y;
		}
	
		snake[snake_lengh-1] = head;
	}
	return 1;
}

int kbhit()                    //实现读入指令和不停顿
{
	struct termios oldt,newt;
	int ch;
	int oldf;

	tcgetattr(STDIN_FILENO,&oldt);
	newt = oldt;
	newt.c_lflag &= ~(ICANON | ECHO);
	tcsetattr(STDIN_FILENO,TCSANOW,&newt);
	oldf = fcntl(STDIN_FILENO,F_GETFL,0);
	fcntl(STDIN_FILENO,F_SETFL,oldf | O_NONBLOCK);

	ch = getchar();

	tcsetattr(STDIN_FILENO,TCSANOW,&oldt);
	fcntl(STDIN_FILENO,F_SETFL,oldf);
	if(ch != EOF)
		return ch;
	else 
		return 0;
}

void main()
{
	int j,t;
	char ch;
	init();
	while(1)               //循环输出
	{
		switch(kbhit())
		{
			case 'w':cur_dir = UP;break;
			case 's':cur_dir = DOWN;break;
			case 'd':cur_dir = RIGHT;break;
			case 'a':cur_dir = LEFT;break;
		}	 
		if(snake_move()==0)
			return ;
		display();
		if(score==50)
		{
			printf("\ngame over .You WIM!\n");
			return ;
		}
		t = score/10+1;
		usleep(1000000/t);
	}
}
